home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / gfx / show / vmpeg.lha / src / amidisplay.c next >
Encoding:
C/C++ Source or Header  |  1999-07-06  |  41.4 KB  |  1,519 lines

  1. /* amidisplay.c, Amiga interface                                              */
  2.  
  3. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  4.  
  5. /*
  6.  * Disclaimer of Warranty
  7.  *
  8.  * These software programs are available to the user without any license fee or
  9.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  10.  * any and all warranties, whether express, implied, or statuary, including any
  11.  * implied warranties or merchantability or of fitness for a particular
  12.  * purpose.  In no event shall the copyright-holder be liable for any
  13.  * incidental, punitive, or consequential damages of any kind whatsoever
  14.  * arising from the use of these programs.
  15.  *
  16.  * This disclaimer of warranty extends to the user of these programs and user's
  17.  * customers, employees, agents, transferees, successors, and assigns.
  18.  *
  19.  * The MPEG Software Simulation Group does not represent or warrant that the
  20.  * programs furnished hereunder are free of infringement of any third-party
  21.  * patents.
  22.  *
  23.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  24.  * are subject to royalty fees to patent holders.  Many of these patents are
  25.  * general enough such that they are unavoidable regardless of implementation
  26.  * design.
  27.  *
  28.  */
  29.  
  30. #ifdef DISPLAY
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35.  
  36. #include "config.h"
  37. #include "global.h"
  38.  
  39. #define CYBERGFXNAME     "cybergraphics.library"
  40. #define CYBERGFXVERSION  40L
  41.  
  42. /* Amiga includes */
  43. #include <dos/dos.h>
  44. #include <exec/exec.h>
  45. #include <dos/dos.h>
  46. #include <graphics/gfx.h>
  47. #include <intuition/intuition.h>
  48. #include <cybergraphics/cybergraphics.h>
  49. #include <libraries/picasso96.h>
  50.  
  51. /* Amiga prototypes */
  52. #include <proto/exec.h>
  53. #include <proto/dos.h>
  54. #include <proto/graphics.h>
  55. #include <proto/intuition.h>
  56. #include <proto/asl.h>
  57. #include <proto/cybergraphics.h>
  58. #include <clib/picasso96_protos.h>
  59. #ifdef __PPC__
  60. #include <clib/powerpc_protos.h>
  61. #endif
  62.  
  63. struct Library *CyberGfxBase = NULL;
  64. struct Library *P96Base = NULL;
  65. struct Window *displayWindow = NULL;
  66. struct Screen *displayScreen = NULL;
  67. struct RastPort *tempRastPort = NULL;
  68. void *Ximage_Ptr, *Ximage_Ptr2;
  69. struct BitMap displayBitMap;
  70. int crv, cbu, cgu, cgv;
  71.  
  72.  
  73. /* private prototypes */
  74. static void Display_Image _ANSI_ARGS_((void *Ximage_Ptr, unsigned char *Dithered_Image));
  75. static void Dither_Frame _ANSI_ARGS_((unsigned char *src[]));
  76. static void Dither_Top_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
  77. static void Dither_Bottom_Field _ANSI_ARGS_((unsigned char *src[], unsigned char *dst));
  78. static void Dither_Top_Field420 _ANSI_ARGS_((unsigned char *src[],
  79.                                       unsigned char *dst));
  80. static void Dither_Bottom_Field420 _ANSI_ARGS_((unsigned char *src[],
  81.                                       unsigned char *dst));
  82. static void  c2p1x1_8_c5_ppc(void *chunky, void *bitplanes,
  83.                              int chunkyx, int chunkyy,
  84.                              int xoffset, int yoffset,
  85.                              int bitplanesize);
  86. static int __amiga_exit(void);
  87. static void __amiga_checkdisplay(void);
  88.  
  89.  
  90. /* local data */
  91. static unsigned char *Dithered_Image = NULL, *Dithered_Image2 = NULL, *Doubled_Image = NULL;
  92.  
  93. static unsigned char Y_Table[256+16];
  94. static unsigned char Cb_Table[128+16];
  95. static unsigned char Cr_Table[128+16];
  96.  
  97. static unsigned char Pixel[256];
  98.  
  99. static int displayIsOpen = FALSE;
  100. static int displayIsNative = TRUE;
  101. static int Width,Height,Depth,BytesPerRow,BytesPerPix,PIPwidth,PIPheight;
  102. static void *GfxAddr;
  103.  
  104.  
  105.  
  106. void Initialize_Display_Process(char *name)
  107. /* connect to server, create and map window,
  108.  * allocate colors and (shared) memory
  109.  */
  110. {
  111.   int Y, Cb, Cr, R, G, B;
  112.   int i;
  113.   unsigned char *temp;
  114.  
  115.   displayIsOpen = TRUE;
  116.   displayBitMap.Planes[0]=0;
  117.   CyberGfxBase = OpenLibrary(CYBERGFXNAME,CYBERGFXVERSION);
  118.  
  119.   /* no mode selected, request one */
  120.   if(Mode_ID == (unsigned long)INVALID_ID && Output_Type < T_AMIGAPIP) {
  121.     if (CyberGfxBase) {
  122.       static short cmodels[] = { PIXFMT_LUT8,PIXFMT_RGB15,
  123.                                  PIXFMT_RGB16,PIXFMT_ARGB32,-1 };
  124.  
  125.       if ((Mode_ID = CModeRequestTags(NULL,
  126.                         CYBRMREQ_CModelArray,(ULONG)cmodels,
  127.                         CYBRMREQ_MinWidth,Coded_Picture_Width*Double_Pixels,
  128.                         CYBRMREQ_MinHeight,Coded_Picture_Height*Double_Pixels,
  129.                         TAG_DONE)) == 0xffffffff)
  130.         Error("No valid screenmode selected\n");
  131.     }
  132.     else {
  133.       struct ScreenModeRequester *sreq = NULL;
  134.  
  135.       if (sreq = (struct ScreenModeRequester *)
  136.          AllocAslRequestTags(ASL_ScreenModeRequest,TAG_END)) {
  137.  
  138.         if (AslRequest(sreq,TAG_END))
  139.           Mode_ID = sreq->sm_DisplayID;
  140.         else
  141.           Error("No valid screenmode selected\n");
  142.         FreeAslRequest(sreq);
  143.       }
  144.     }
  145.     printf("Next time, use option -m0x%lx\n",Mode_ID);
  146.   }
  147.  
  148.   /* native display mode ? */
  149.   if (CyberGfxBase)
  150.     if (IsCyberModeID(Mode_ID))
  151.       displayIsNative = FALSE;
  152.  
  153.   if (Output_Type == T_AMIGAPIP) {
  154.     if (P96Base = OpenLibrary("Picasso96API.library",0))
  155.       displayIsNative = FALSE;
  156.     else
  157.       Error("Picasso96 not available!\n");
  158.   }
  159.  
  160.   /* setup automatically closing of the display */
  161.  
  162. /*  if(onbreak(&__amiga_exit)) Error("onbreak failed\n");*/
  163.   if(atexit(&__amiga_checkdisplay)) Error("atexit failed\n");
  164.  
  165.   /* open screen */
  166.  
  167.   if (displayIsNative) {
  168.     Depth = 8;
  169.  
  170.     if (!(temp = (unsigned char *)
  171.         AllocRaster(Coded_Picture_Width*Double_Pixels,
  172.                     Coded_Picture_Height*Double_Pixels*8)) )
  173.       Error("AllocRaster failed\n");
  174.  
  175.     /* initialize bitmap */
  176.  
  177.     InitBitMap(&displayBitMap, 8, Coded_Picture_Width*Double_Pixels,
  178.                Coded_Picture_Height*Double_Pixels);
  179.  
  180.     /* attach image data to bitmap */
  181.  
  182.     for (i=0; i<8; i++)
  183.       displayBitMap.Planes[i] = temp + i * RASSIZE(Coded_Picture_Width*Double_Pixels, Coded_Picture_Height*Double_Pixels);
  184.  
  185.     if (!(displayScreen = OpenScreenTags(NULL,
  186.               SA_BitMap,&displayBitMap,
  187.               SA_Width,Coded_Picture_Width*Double_Pixels,
  188.               SA_Height,Coded_Picture_Height*Double_Pixels,
  189.               SA_Title,"VMPEG",
  190.               SA_DisplayID,Mode_ID,
  191.               SA_Depth,8,
  192.               SA_ShowTitle,FALSE,
  193.               TAG_END)))
  194.       Error("OpenScreenTags failed\n");
  195.   }
  196.  
  197.   else if (Output_Type != T_AMIGAPIP) {
  198.     /* CyberGfx display */
  199.  
  200.     Width = GetCyberIDAttr(CYBRIDATTR_WIDTH,Mode_ID);
  201.     Height = GetCyberIDAttr(CYBRIDATTR_HEIGHT,Mode_ID);
  202.     Depth = GetCyberIDAttr(CYBRIDATTR_DEPTH,Mode_ID);
  203.     if (!(displayScreen = OpenScreenTags(NULL,
  204.                                          SA_Width,Width,
  205.                                          SA_Height,Height,
  206.                                          SA_Title,"VMPEG",
  207.                                          SA_DisplayID,Mode_ID,
  208.                                          SA_Depth,Depth,
  209.                                          SA_ShowTitle,FALSE,
  210.                                          TAG_END)))
  211.       Error("OpenScreenTags failed\n");
  212.  
  213.     BytesPerRow = GetCyberMapAttr(displayScreen->RastPort.BitMap,
  214.                                   CYBRMATTR_XMOD);
  215.     BytesPerPix = GetCyberMapAttr(displayScreen->RastPort.BitMap,
  216.                                   CYBRMATTR_BPPIX);
  217.     GfxAddr = (void *)GetCyberMapAttr(displayScreen->RastPort.BitMap,
  218.                                       CYBRMATTR_DISPADR);
  219.     /* center display */
  220.     if (Height > Coded_Picture_Height*Double_Pixels)
  221.       GfxAddr = (void *)((char *)GfxAddr + BytesPerRow *
  222.                          ((Height-Coded_Picture_Height*Double_Pixels)>>1));
  223.     if (Width > Coded_Picture_Width*Double_Pixels)
  224.       GfxAddr = (void *)((char *)GfxAddr + (BytesPerPix *
  225.                          ((Width - Coded_Picture_Width*Double_Pixels)
  226.                           >> 1) & ~15));
  227.   }
  228.  
  229.   if (Output_Type == T_AMIGAPIP) {
  230.     /* Picaoss96 PIP window */
  231.  
  232.     struct TagItem piptags[] = {
  233.       P96PIP_SourceFormat, RGBFB_Y4U2V2,
  234.       P96PIP_SourceWidth, 0,
  235.       P96PIP_SourceHeight, 0,
  236.       P96PIP_InitialIntScaling,TRUE,
  237.       P96PIP_AllowCropping,TRUE,
  238.       WA_Title, (ULONG)"VMPEG Display",
  239.       WA_Activate, TRUE,
  240.       WA_RMBTrap, TRUE,
  241.       WA_Width, 0,
  242.       WA_Height, 0,
  243.       WA_DragBar,TRUE,
  244.       WA_DepthGadget,TRUE,
  245.       WA_IDCMP,IDCMP_RAWKEY,
  246.       WA_NewLookMenus,TRUE,
  247.       WA_PubScreenName, (ULONG)"Workbench",
  248.       TAG_DONE,0
  249.     };
  250.  
  251.     piptags[1].ti_Data = Coded_Picture_Width;
  252.     piptags[2].ti_Data = Coded_Picture_Height;
  253.     piptags[8].ti_Data = Coded_Picture_Width*Double_Pixels;
  254.     piptags[9].ti_Data = Coded_Picture_Height*Double_Pixels;
  255.     PIPwidth = ((Coded_Picture_Width+15)&~15)>>1;
  256.     PIPheight = Coded_Picture_Height>>1;
  257.     if (displayWindow = p96PIP_OpenTagList(piptags)) {
  258.       int x,y;
  259.       struct TagItem gtTags[] = {
  260.         {P96PIP_SourceBitMap,0},{TAG_DONE, 0}
  261.       };
  262.       struct RenderInfo renderinfo;
  263.       struct BitMap *bitmap;
  264.       LONG lock;
  265.  
  266.       gtTags[0].ti_Data = (ULONG)&bitmap;
  267.       p96PIP_GetTagList(displayWindow,gtTags);
  268.       lock = p96LockBitMap(bitmap,(UBYTE *)&renderinfo,
  269.                            sizeof(struct RenderInfo));
  270.       GfxAddr = (void *)renderinfo.Memory;
  271.       p96UnlockBitMap(bitmap, lock);
  272.       Depth = 24;
  273.     }
  274.     else
  275.       Error("PIP window not supported by hardware\n");
  276.   }
  277.  
  278.   else {
  279.     /* open window on screen */
  280.     
  281.     if (!(displayWindow = OpenWindowTags(NULL,WA_CustomScreen,displayScreen,
  282.             WA_Title,"VMPEG Display",
  283.             WA_Width,Width,
  284.             WA_Height,Height,
  285.             WA_IDCMP,IDCMP_RAWKEY,
  286.             WA_Backdrop,TRUE,
  287.             WA_Borderless,TRUE,
  288.             WA_RMBTrap,TRUE,
  289.             WA_Activate,TRUE,
  290.             WA_NewLookMenus,TRUE,
  291.             WA_ScreenTitle,"VMPEG",
  292.             TAG_END)))
  293.       Error("OpenWindowTags failed\n");
  294.   }
  295.  
  296.   /* matrix coefficients */
  297.  
  298.   crv = Inverse_Table_6_9[matrix_coefficients][0];
  299.   cbu = Inverse_Table_6_9[matrix_coefficients][1];
  300.   cgu = Inverse_Table_6_9[matrix_coefficients][2];
  301.   cgv = Inverse_Table_6_9[matrix_coefficients][3];
  302.  
  303.   /* allocate colors */
  304.  
  305.   /* color allocation:
  306.   * i is the (internal) 8 bit color number, it consists of separate
  307.   * bit fields for Y, U and V: i = (yyyyuuvv), we don't use yyyy=0000
  308.   * and yyyy=1111, this leaves 32 colors for other applications
  309.   *
  310.   * the allocated colors correspond to the following Y, U and V values:
  311.   * Y:   24, 40, 56, 72, 88, 104, 120, 136, 152, 168, 184, 200, 216, 232
  312.   * U,V: -48, -16, 16, 48
  313.   *
  314.   * U and V values span only about half the color space; this gives
  315.   * usually much better quality, although highly saturated colors can
  316.   * not be displayed properly
  317.   *
  318.   * translation to R,G,B is implicitly done by the color look-up table
  319.   */
  320.  
  321.   for (i=0; i<256; i++)
  322.     /* clear to make sure that all colors are correctly freed */
  323.     Pixel[i] = 0xff;
  324.  
  325.   for (i=16; i<240; i++) {
  326.     /* color space conversion */
  327.  
  328.     Y  = 16*((i>>4)&15) + 8;
  329.     Cb = 32*((i>>2)&3)  - 48;
  330.     Cr = 32*(i&3)       - 48;
  331.  
  332.     Y = 76309 * (Y - 16); /* (255/219)*65536 */
  333.  
  334.     R = Clip[(Y + crv*Cr + 32768)>>16];
  335.     G = Clip[(Y - cgu*Cb - cgv*Cr + 32768)>>16];
  336.     B = Clip[(Y + cbu*Cb + 32786)>>16];
  337.  
  338.     if (Depth == 8)
  339.       SetRGB32(&displayScreen->ViewPort,i,R<<24,G<<24,B<<24);
  340.     Pixel[i] = i;
  341.   }
  342.  
  343.   /* allocate temporary rastport */
  344.  
  345.   if (!(tempRastPort = malloc(sizeof(struct RastPort))))
  346.     Error("malloc failed\n");
  347.  
  348.   /* allocate buffers */
  349.  
  350.   if (!(Dithered_Image = (unsigned char *)
  351.       malloc((Coded_Picture_Width)*(Coded_Picture_Height)*4)))
  352.     Error("malloc failed\n");
  353.  
  354.   if (!progressive_sequence)
  355.     if (!(Dithered_Image2 = (unsigned char *)
  356.         malloc((Coded_Picture_Width)*(Coded_Picture_Height))))
  357.       Error("malloc failed\n");
  358.  
  359.   if (!(Doubled_Image = (unsigned char *)
  360.       malloc((Coded_Picture_Width*Double_Pixels)*
  361.              (Coded_Picture_Height*Double_Pixels))))
  362.     Error("malloc failed\n");
  363. }
  364.  
  365.  
  366. static int __amiga_exit(void)
  367. {
  368.   fprintf(stderr,"CTRL-C received\n");
  369.   return 1;
  370. }
  371.  
  372.  
  373. static void __amiga_checkdisplay(void)
  374. {
  375.   if(displayIsOpen) Terminate_Display_Process();
  376. }
  377.  
  378.  
  379. void Terminate_Display_Process()
  380. {
  381.   int i;
  382.  
  383.   if(Doubled_Image) {
  384.     free(Doubled_Image);
  385.     Doubled_Image = NULL;
  386.   }
  387.   if(Dithered_Image2) {
  388.     free(Dithered_Image2);
  389.     Dithered_Image2 = NULL;
  390.   }
  391.   if(Dithered_Image) {
  392.     free(Dithered_Image);
  393.     Dithered_Image = NULL;
  394.   }
  395.  
  396.   if (displayWindow) {
  397.     if (Output_Type == T_AMIGAPIP)
  398.       p96PIP_Close(displayWindow);
  399.     else
  400.       CloseWindow(displayWindow);
  401.   }
  402.   if (displayScreen)
  403.     CloseScreen(displayScreen);
  404.  
  405.   if(displayBitMap.Planes[0]) {
  406.     FreeRaster(displayBitMap.Planes[0],Coded_Picture_Width*Double_Pixels,Coded_Picture_Height*Double_Pixels*8);
  407.     displayBitMap.Planes[0]=NULL;
  408.   }
  409.   displayIsOpen = FALSE;
  410.  
  411.   /* close libraries */
  412.  
  413.   if (P96Base) {
  414.     CloseLibrary(P96Base);
  415.     P96Base = NULL;
  416.   }
  417.   if (CyberGfxBase) {
  418.     CloseLibrary(CyberGfxBase);
  419.     CyberGfxBase = NULL;
  420.   }
  421. }
  422.  
  423.  
  424. #ifdef __PPC__
  425. static void Display_Fps()
  426. {
  427.   static char buf[8];
  428.  
  429.   sprintf(buf,"%3.1f",real_frame_rate);
  430.   Move(&displayScreen->RastPort,0,10);
  431.   Text(&displayScreen->RastPort,buf,strlen(buf));
  432. }
  433. #endif
  434.  
  435.  
  436. static void show_timecode()
  437. {
  438.   static char buf[12];
  439.  
  440.   sprintf(buf,"%02d:%02d:%02d",hour,minute,sec);
  441.   Move(&displayScreen->RastPort,
  442.        Coded_Picture_Width>>1,Coded_Picture_Height>>1);
  443.   Text(&displayScreen->RastPort,buf,8);
  444. }
  445.  
  446.  
  447. static void Display_Image(void *Ximage_Ptr,unsigned char *Dithered_Image)
  448. {
  449.   /* scale picture to the double if -h is present */
  450.   if(Double_Pixels == 2)
  451.   {
  452.     int i,j;
  453.     unsigned char *dest_pointer = Doubled_Image;
  454.     unsigned char *source_pointer = Dithered_Image;
  455.     for(i=0;i<Coded_Picture_Height;i++)
  456.     {
  457.       for(j=0;j<Coded_Picture_Width;j++)
  458.       {
  459.         *(dest_pointer++)=*source_pointer;
  460.         *(dest_pointer++)=*(source_pointer++);
  461.       }
  462.       source_pointer-=Coded_Picture_Width;
  463.       for(j=0;j<Coded_Picture_Width;j++)
  464.       {
  465.         *(dest_pointer)++=*source_pointer;
  466.         *(dest_pointer)++=*(source_pointer++);
  467.       }
  468.     }
  469.  
  470.     Dithered_Image = Doubled_Image;
  471.   }
  472.  
  473.   if (displayIsNative) {
  474.     c2p1x1_8_c5_ppc(Dithered_Image,displayBitMap.Planes[0],
  475.                     Coded_Picture_Width*Double_Pixels,
  476.                     Coded_Picture_Height*Double_Pixels, 0, 0,
  477.                     ((Coded_Picture_Width*Double_Pixels) *
  478.                     (Coded_Picture_Height*Double_Pixels)) >> 3);
  479.   }
  480.   else {
  481. #ifdef __PPC__
  482.     if (Output_Type == T_AMIGADIRECT)
  483.       WriteFrame8(Dithered_Image,GfxAddr,BytesPerRow,
  484.                   Coded_Picture_Width*Double_Pixels,
  485.                   Coded_Picture_Height*Double_Pixels);
  486.     else
  487. #endif
  488.       WritePixelArray8(&displayScreen->RastPort,0,0,
  489.                        (Coded_Picture_Width*Double_Pixels)-1,
  490.                        (Coded_Picture_Height*Double_Pixels)-1,
  491.                        Dithered_Image,&displayScreen->RastPort);
  492.   }
  493.  
  494. #ifdef __PPC__
  495.   if (Fps_Flag)
  496.     Display_Fps();
  497. #endif
  498. }
  499.  
  500.  
  501. static void WriteARGBPixelArray(unsigned char *src[],unsigned char *dst)
  502. {
  503.   unsigned char *py1,*py2,*pu,*pv;
  504.   unsigned char *buf = Dithered_Image;
  505.   int y,u,v,i,j;
  506.   int bpr = Coded_Picture_Width*4;
  507.   ULONG d;
  508.  
  509.   py1 = src[0];
  510.   py2 = src[0]+Coded_Picture_Width;
  511.   pu = src[1];
  512.   pv = src[2];
  513.   for (j=0; j<Coded_Picture_Height; j+=2, buf+=bpr,
  514.        py1+=Coded_Picture_Width,py2+=Coded_Picture_Width) {
  515.  
  516.     for (i=0; i<Coded_Picture_Width; i+=2, buf+=8) {
  517.       u = *pu++ - 128;
  518.       v = *pv++ - 128;
  519.  
  520.       y = 76309 * ((int)*py1++ - 16); /* (255/219)*65536 */
  521.       d = ((Clip[(y + crv*v + 32768)>>16] & 0xff) << 16) |
  522.           ((Clip[(y - cgu*u -cgv*v + 32768)>>16] & 0xff) << 8) |
  523.           (Clip[(y + cbu*u + 32786)>>16] & 0xff);
  524.       *(ULONG *)(buf+0) = d;
  525.  
  526.       y = 76309 * ((int)*py1++ - 16); /* (255/219)*65536 */
  527.       d = ((Clip[(y + crv*v + 32768)>>16] & 0xff) << 16) |
  528.           ((Clip[(y - cgu*u -cgv*v + 32768)>>16] & 0xff) << 8) |
  529.           (Clip[(y + cbu*u + 32786)>>16] & 0xff);
  530.       *(ULONG *)(buf+4) = d;
  531.  
  532.       y = 76309 * ((int)*py2++ - 16); /* (255/219)*65536 */
  533.       d = ((Clip[(y + crv*v + 32768)>>16] & 0xff) << 16) |
  534.           ((Clip[(y - cgu*u -cgv*v + 32768)>>16] & 0xff) << 8) |
  535.           (Clip[(y + cbu*u + 32786)>>16] & 0xff);
  536.       *(ULONG *)(buf+bpr) = d;
  537.  
  538.       y = 76309 * ((int)*py2++ - 16); /* (255/219)*65536 */
  539.       d = ((Clip[(y + crv*v + 32768)>>16] & 0xff) << 16) |
  540.           ((Clip[(y - cgu*u -cgv*v + 32768)>>16] & 0xff) << 8) |
  541.           (Clip[(y + cbu*u + 32786)>>16] & 0xff);
  542.       *(ULONG *)(buf+bpr+4) = d;
  543.     }
  544.   }
  545.   WritePixelArray(Dithered_Image,0,0,bpr,&displayScreen->RastPort,0,0,
  546.                   Coded_Picture_Width,Coded_Picture_Height,RECTFMT_ARGB);
  547. }
  548.  
  549.  
  550. static void Display_Truecolor(unsigned char *src[],unsigned char *dst)
  551. {
  552. #ifdef __PPC__
  553.   if (Output_Type == T_AMIGADIRECT) {
  554.     int modulo = BytesPerRow - Coded_Picture_Width * BytesPerPix;
  555.  
  556.     switch (Depth) {
  557.  
  558.       case 15:  /* RGB15 */
  559.         WriteFrame15(src,dst,Coded_Picture_Width,Coded_Picture_Height,
  560.                      BytesPerRow,modulo);
  561.         break;
  562.  
  563.       case 16:  /* RGB16 */
  564.         WriteFrame16(src,dst,Coded_Picture_Width,Coded_Picture_Height,
  565.                      BytesPerRow,modulo);
  566.         break;
  567.  
  568.       case 32:  /* RGB32 */
  569.       case 24:  /* ... is reporting depth 24? Hmm... */
  570.         WriteFrame32(src,dst,Coded_Picture_Width,Coded_Picture_Height,
  571.                      BytesPerRow,modulo);
  572.         break;
  573.     }
  574.   }
  575.   else
  576. #endif
  577.     WriteARGBPixelArray(src,dst);
  578.  
  579. #ifdef __PPC__
  580.   if (Fps_Flag)
  581.     Display_Fps();
  582. #endif
  583. }
  584.  
  585.  
  586. void Display_Second_Field()
  587. {
  588.   Display_Image(Ximage_Ptr2,Dithered_Image2);
  589.  
  590.   /* @@@ what happens for true color ? */
  591. }
  592.  
  593.  
  594. void Initialize_Dither_Matrix()
  595. /* 4x4 ordered dither
  596.  *
  597.  * threshold pattern:
  598.  *   0  8  2 10
  599.  *  12  4 14  6
  600.  *   3 11  1  9
  601.  *  15  7 13  5
  602.  */
  603. {
  604.   int i, v;
  605.  
  606.   for (i=-8; i<256+8; i++)
  607.   {
  608.     v = i>>4;
  609.     if (v<1)
  610.       v = 1;
  611.     else if (v>14)
  612.       v = 14;
  613.     Y_Table[i+8] = v<<4;
  614.   }
  615.  
  616.   for (i=0; i<128+16; i++)
  617.   {
  618.     v = (i-40)>>4;
  619.     if (v<0)
  620.       v = 0;
  621.     else if (v>3)
  622.       v = 3;
  623.     Cb_Table[i] = v<<2;
  624.     Cr_Table[i] = v;
  625.   }
  626. }
  627.  
  628.  
  629. void dither(unsigned char *src[])
  630. {
  631.   /* should this test only the display flag, not progressive_sequence ? --CF */
  632.   /* CHANGE 95/05/13: progressive_sequence->progressive_frame */
  633.   static unsigned char *lmb = (unsigned char *)0xbfe001;
  634.   static unsigned short *rmb = (unsigned short *)0xdff016;
  635.   static unsigned char *keyc = (unsigned char *)0xbfec01;
  636.  
  637.   if ((*lmb & 0x40)==0 || *keyc==0x75)
  638.     /* left mouse button or ESC-key quits */
  639.     exit(0);
  640.  
  641.   if (Depth <= 8) {
  642.  
  643.     if (progressive_frame || Display_Progressive_Flag)
  644.     Dither_Frame(src);
  645.     else
  646.     {
  647.       if ((picture_structure==FRAME_PICTURE && top_field_first) || picture_structure==BOTTOM_FIELD)
  648.       {
  649.         /* top field first */
  650.         if (chroma_format==CHROMA420 && hiQdither)
  651.         {
  652.           Dither_Top_Field420(src,Dithered_Image);
  653.           Dither_Bottom_Field420(src,Dithered_Image2);
  654.         }
  655.         else
  656.         {
  657.           Dither_Top_Field(src,Dithered_Image);
  658.           Dither_Bottom_Field(src,Dithered_Image2);
  659.         }
  660.       }
  661.       else
  662.       {
  663.         /* bottom field first */
  664.         if (chroma_format==CHROMA420 && hiQdither)
  665.         {
  666.           Dither_Bottom_Field420(src,Dithered_Image);
  667.           Dither_Top_Field420(src,Dithered_Image2);
  668.         }
  669.         else
  670.         {
  671.           Dither_Bottom_Field(src,Dithered_Image);
  672.           Dither_Top_Field(src,Dithered_Image2);
  673.         }
  674.       }
  675.     }
  676.  
  677.     Display_Image(Ximage_Ptr,Dithered_Image);
  678.   }
  679.  
  680.   else if (Output_Type == T_AMIGAPIP)
  681.     /* Picasso96 PIP window */
  682.     yuv2pip(GfxAddr,src,PIPwidth,PIPheight,0);
  683.  
  684.   else
  685.     /* 15/16/24/32 bit direct yuv to rgb conversion */
  686.     Display_Truecolor(src,(unsigned char *)GfxAddr);
  687.  
  688.   if (TimeCode_Flag)
  689.     show_timecode();
  690. }
  691.  
  692.  
  693. static void Dither_Frame(unsigned char *src[])
  694. {
  695.   int i,j;
  696.   int y,u,v;
  697.   unsigned char *py,*pu,*pv,*dst;
  698.  
  699.   py = src[0];
  700.   pu = src[1];
  701.   pv = src[2];
  702.   dst = Dithered_Image;
  703.  
  704.   for (j=0; j<Coded_Picture_Height; j+=4)
  705.   {
  706.     /* line j + 0 */
  707.     for (i=0; i<Coded_Picture_Width; i+=4)
  708.     {
  709.       y = *py++;
  710.       u = *pu++ >> 1;
  711.       v = *pv++ >> 1;
  712.       *dst++ = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]];
  713.       y = *py++;
  714.       if (chroma_format==CHROMA444)
  715.       {
  716.         u = *pu++ >> 1;
  717.         v = *pv++ >> 1;
  718.       }
  719.       *dst++ = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]];
  720.       y = *py++;
  721.       u = *pu++ >> 1;
  722.       v = *pv++ >> 1;
  723.       *dst++ = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]];
  724.       y = *py++;
  725.       if (chroma_format==CHROMA444)
  726.       {
  727.         u = *pu++ >> 1;
  728.         v = *pv++ >> 1;
  729.       }
  730.       *dst++ = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]];
  731.     }
  732.  
  733.     if (chroma_format==CHROMA420)
  734.     {
  735.       pu -= Chroma_Width;
  736.       pv -= Chroma_Width;
  737.     }
  738.  
  739.     /* line j + 1 */
  740.     for (i=0; i<Coded_Picture_Width; i+=4)
  741.     {
  742.       y = *py++;
  743.       u = *pu++ >> 1;
  744.       v = *pv++ >> 1;
  745.       *dst++ = Pixel[Y_Table[y+12]|Cb_Table[u+12]|Cr_Table[v+12]];
  746.       y = *py++;
  747.       if (chroma_format==CHROMA444)
  748.       {
  749.         u = *pu++ >> 1;
  750.         v = *pv++ >> 1;
  751.       }
  752.       *dst++ = Pixel[Y_Table[y+4]|Cb_Table[u+4]|Cr_Table[v+4]];
  753.       y = *py++;
  754.       u = *pu++ >> 1;
  755.       v = *pv++ >> 1;
  756.       *dst++ = Pixel[Y_Table[y+14]|Cb_Table[u+14]|Cr_Table[v+14]];
  757.       y = *py++;
  758.       if (chroma_format==CHROMA444)
  759.       {
  760.         u = *pu++ >> 1;
  761.         v = *pv++ >> 1;
  762.       }
  763.       *dst++ = Pixel[Y_Table[y+6]|Cb_Table[u+6]|Cr_Table[v+6]];
  764.     }
  765.  
  766.     /* line j + 2 */
  767.     for (i=0; i<Coded_Picture_Width; i+=4)
  768.     {
  769.       y = *py++;
  770.       u = *pu++ >> 1;
  771.       v = *pv++ >> 1;
  772.       *dst++ = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]];
  773.       y = *py++;
  774.       if (chroma_format==CHROMA444)
  775.       {
  776.         u = *pu++ >> 1;
  777.         v = *pv++ >> 1;
  778.       }
  779.       *dst++ = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]];
  780.       y = *py++;
  781.       u = *pu++ >> 1;
  782.       v = *pv++ >> 1;
  783.       *dst++ = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]];
  784.       y = *py++;
  785.       if (chroma_format==CHROMA444)
  786.       {
  787.         u = *pu++ >> 1;
  788.         v = *pv++ >> 1;
  789.       }
  790.       *dst++ = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]];
  791.     }
  792.  
  793.     if (chroma_format==CHROMA420)
  794.     {
  795.       pu -= Chroma_Width;
  796.       pv -= Chroma_Width;
  797.     }
  798.  
  799.     /* line j + 3 */
  800.     for (i=0; i<Coded_Picture_Width; i+=4)
  801.     {
  802.       y = *py++;
  803.       u = *pu++ >> 1;
  804.       v = *pv++ >> 1;
  805.       *dst++ = Pixel[Y_Table[y+15]|Cb_Table[u+15]|Cr_Table[v+15]];
  806.       y = *py++;
  807.       if (chroma_format==CHROMA444)
  808.       {
  809.         u = *pu++ >> 1;
  810.         v = *pv++ >> 1;
  811.       }
  812.       *dst++ = Pixel[Y_Table[y+7]|Cb_Table[u+7]|Cr_Table[v+7]];
  813.       y = *py++;
  814.       u = *pu++ >> 1;
  815.       v = *pv++ >> 1;
  816.       *dst++ = Pixel[Y_Table[y+13]|Cb_Table[u+13]|Cr_Table[v+13]];
  817.       y = *py++;
  818.       if (chroma_format==CHROMA444)
  819.       {
  820.         u = *pu++ >> 1;
  821.         v = *pv++ >> 1;
  822.       }
  823.       *dst++ = Pixel[Y_Table[y+5]|Cb_Table[u+5]|Cr_Table[v+5]];
  824.     }
  825.   }
  826.  
  827. }
  828.  
  829.  
  830. static void Dither_Top_Field(unsigned char *src[],unsigned char *dst)
  831. {
  832.   int i,j;
  833.   int y,Y2,u,v;
  834.   unsigned char *py,*Y2_ptr,*pu,*pv,*dst2;
  835.  
  836.   py = src[0];
  837.   Y2_ptr = src[0] + (Coded_Picture_Width<<1);
  838.   pu = src[1];
  839.   pv = src[2];
  840.   dst2 = dst + Coded_Picture_Width;
  841.  
  842.   for (j=0; j<Coded_Picture_Height; j+=4)
  843.   {
  844.     /* line j + 0, j + 1 */
  845.     for (i=0; i<Coded_Picture_Width; i+=4)
  846.     {
  847.       y = *py++;
  848.       Y2 = *Y2_ptr++;
  849.       u = *pu++ >> 1;
  850.       v = *pv++ >> 1;
  851.       *dst++  = Pixel[Y_Table[y]|Cb_Table[u]|Cr_Table[v]];
  852.       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+12]|Cb_Table[u+12]|Cr_Table[v+12]];
  853.  
  854.       y = *py++;
  855.       Y2 = *Y2_ptr++;
  856.       if (chroma_format==CHROMA444)
  857.       {
  858.         u = *pu++ >> 1;
  859.         v = *pv++ >> 1;
  860.       }
  861.       *dst++  = Pixel[Y_Table[y+8]|Cb_Table[u+8]|Cr_Table[v+8]];
  862.       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+4]|Cb_Table[u+4]|Cr_Table[v+4]];
  863.  
  864.       y = *py++;
  865.       Y2 = *Y2_ptr++;
  866.       u = *pu++ >> 1;
  867.       v = *pv++ >> 1;
  868.       *dst++  = Pixel[Y_Table[y+2]|Cb_Table[u+2]|Cr_Table[v+2]];
  869.       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+14]|Cb_Table[u+14]|Cr_Table[v+14]];
  870.  
  871.       y = *py++;
  872.       Y2 = *Y2_ptr++;
  873.       if (chroma_format==CHROMA444)
  874.       {
  875.         u = *pu++ >> 1;
  876.         v = *pv++ >> 1;
  877.       }
  878.       *dst++  = Pixel[Y_Table[y+10]|Cb_Table[u+10]|Cr_Table[v+10]];
  879.       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+6]|Cb_Table[u+6]|Cr_Table[v+6]];
  880.     }
  881.  
  882.     py += Coded_Picture_Width;
  883.  
  884.     if (j!=(Coded_Picture_Height-4))
  885.       Y2_ptr += Coded_Picture_Width;
  886.     else
  887.       Y2_ptr -= Coded_Picture_Width;
  888.  
  889.     dst += Coded_Picture_Width;
  890.     dst2 += Coded_Picture_Width;
  891.  
  892.     if (chroma_format==CHROMA420)
  893.     {
  894.       pu -= Chroma_Width;
  895.       pv -= Chroma_Width;
  896.     }
  897.     else
  898.     {
  899.       pu += Chroma_Width;
  900.       pv += Chroma_Width;
  901.     }
  902.  
  903.     /* line j + 2, j + 3 */
  904.     for (i=0; i<Coded_Picture_Width; i+=4)
  905.     {
  906.       y = *py++;
  907.       Y2 = *Y2_ptr++;
  908.       u = *pu++ >> 1;
  909.       v = *pv++ >> 1;
  910.       *dst++  = Pixel[Y_Table[y+3]|Cb_Table[u+3]|Cr_Table[v+3]];
  911.       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+15]|Cb_Table[u+15]|Cr_Table[v+15]];
  912.  
  913.       y = *py++;
  914.       Y2 = *Y2_ptr++;
  915.       if (chroma_format==CHROMA444)
  916.       {
  917.         u = *pu++ >> 1;
  918.         v = *pv++ >> 1;
  919.       }
  920.       *dst++  = Pixel[Y_Table[y+11]|Cb_Table[u+11]|Cr_Table[v+11]];
  921.       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+7]|Cb_Table[u+7]|Cr_Table[v+7]];
  922.  
  923.       y = *py++;
  924.       Y2 = *Y2_ptr++;
  925.       u = *pu++ >> 1;
  926.       v = *pv++ >> 1;
  927.       *dst++  = Pixel[Y_Table[y+1]|Cb_Table[u+1]|Cr_Table[v+1]];
  928.       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+13]|Cb_Table[u+13]|Cr_Table[v+13]];
  929.  
  930.       y = *py++;
  931.       Y2 = *Y2_ptr++;
  932.       if (chroma_format==CHROMA444)
  933.       {
  934.         u = *pu++ >> 1;
  935.         v = *pv++ >> 1;
  936.       }
  937.       *dst++  = Pixel[Y_Table[y+9]|Cb_Table[u+9]|Cr_Table[v+9]];
  938.       *dst2++ = Pixel[Y_Table[((y+Y2)>>1)+5]|Cb_Table[u+5]|Cr_Table[v+5]];
  939.     }
  940.  
  941.     py += Coded_Picture_Width;
  942.     Y2_ptr += Coded_Picture_Width;
  943.     dst += Coded_Picture_Width;
  944.     dst2 += Coded_Picture_Width;
  945.     pu += Chroma_Width;
  946.     pv += Chroma_Width;
  947.   }
  948. }
  949.  
  950.  
  951. static void Dither_Bottom_Field(unsigned char *src[],unsigned char *dst)
  952. {
  953.   int i,j;
  954.   int y,Y2,u,v;
  955.   unsigned char *py,*Y2_ptr,*pu,*pv,*dst2;
  956.  
  957.   py = src[0] + Coded_Picture_Width;
  958.   Y2_ptr = py;
  959.   pu = src[1] + Chroma_Width;
  960.   pv = src[2] + Chroma_Width;
  961.   dst2 = dst + Coded_Picture_Width;
  962.  
  963.   for (j=0; j<Coded_Picture_Height; j+=4)
  964.   {
  965.     /* line j + 0, j + 1 */
  966.     for (i=0; i<Coded_Picture_Width; i+=4)
  967.     {
  968.       y = *py++;
  969.       Y2 = *Y2_ptr++;
  970.       u = *pu++ >> 1;
  971.       v = *pv++ >> 1;
  972.       *dst++  = Pixel[Y_Table[((y+Y2)>>1)]|Cb_Table[u]|Cr_Table[v]];
  973.       *dst2++ = Pixel[Y_Table[Y2+12]|Cb_Table[u+12]|Cr_Table[v+12]];
  974.  
  975.       y = *py++;
  976.       Y2 = *Y2_ptr++;
  977.       if (chroma_format==CHROMA444)
  978.       {
  979.         u = *pu++ >> 1;
  980.         v = *pv++ >> 1;
  981.       }
  982.       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+8]|Cb_Table[u+8]|Cr_Table[v+8]];
  983.       *dst2++ = Pixel[Y_Table[Y2+4]|Cb_Table[u+4]|Cr_Table[v+4]];
  984.  
  985.       y = *py++;
  986.       Y2 = *Y2_ptr++;
  987.       u = *pu++ >> 1;
  988.       v = *pv++ >> 1;
  989.       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+2]|Cb_Table[u+2]|Cr_Table[v+2]];
  990.       *dst2++ = Pixel[Y_Table[Y2+14]|Cb_Table[u+14]|Cr_Table[v+14]];
  991.  
  992.       y = *py++;
  993.       Y2 = *Y2_ptr++;
  994.       if (chroma_format==CHROMA444)
  995.       {
  996.         u = *pu++ >> 1;
  997.         v = *pv++ >> 1;
  998.       }
  999.       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+10]|Cb_Table[u+10]|Cr_Table[v+10]];
  1000.       *dst2++ = Pixel[Y_Table[Y2+6]|Cb_Table[u+6]|Cr_Table[v+6]];
  1001.     }
  1002.  
  1003.     if (j==0)
  1004.       py -= Coded_Picture_Width;
  1005.     else
  1006.       py += Coded_Picture_Width;
  1007.  
  1008.     Y2_ptr += Coded_Picture_Width;
  1009.     dst += Coded_Picture_Width;
  1010.     dst2 += Coded_Picture_Width;
  1011.  
  1012.     if (chroma_format==CHROMA420)
  1013.     {
  1014.       pu -= Chroma_Width;
  1015.       pv -= Chroma_Width;
  1016.     }
  1017.     else
  1018.     {
  1019.       pu += Chroma_Width;
  1020.       pv += Chroma_Width;
  1021.     }
  1022.  
  1023.     /* line j + 2. j + 3 */
  1024.     for (i=0; i<Coded_Picture_Width; i+=4)
  1025.     {
  1026.       y = *py++;
  1027.       Y2 = *Y2_ptr++;
  1028.       u = *pu++ >> 1;
  1029.       v = *pv++ >> 1;
  1030.       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+3]|Cb_Table[u+3]|Cr_Table[v+3]];
  1031.       *dst2++ = Pixel[Y_Table[Y2+15]|Cb_Table[u+15]|Cr_Table[v+15]];
  1032.  
  1033.       y = *py++;
  1034.       Y2 = *Y2_ptr++;
  1035.       if (chroma_format==CHROMA444)
  1036.       {
  1037.         u = *pu++ >> 1;
  1038.         v = *pv++ >> 1;
  1039.       }
  1040.       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+11]|Cb_Table[u+11]|Cr_Table[v+11]];
  1041.       *dst2++ = Pixel[Y_Table[Y2+7]|Cb_Table[u+7]|Cr_Table[v+7]];
  1042.  
  1043.       y = *py++;
  1044.       Y2 = *Y2_ptr++;
  1045.       u = *pu++ >> 1;
  1046.       v = *pv++ >> 1;
  1047.       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+1]|Cb_Table[u+1]|Cr_Table[v+1]];
  1048.       *dst2++ = Pixel[Y_Table[Y2+13]|Cb_Table[u+13]|Cr_Table[v+13]];
  1049.  
  1050.       y = *py++;
  1051.       Y2 = *Y2_ptr++;
  1052.       if (chroma_format==CHROMA444)
  1053.       {
  1054.         u = *pu++ >> 1;
  1055.         v = *pv++ >> 1;
  1056.       }
  1057.       *dst++  = Pixel[Y_Table[((y+Y2)>>1)+9]|Cb_Table[u+9]|Cr_Table[v+9]];
  1058.       *dst2++ = Pixel[Y_Table[Y2+5]|Cb_Table[u+5]|Cr_Table[v+5]];
  1059.     }
  1060.  
  1061.     py += Coded_Picture_Width;
  1062.     Y2_ptr += Coded_Picture_Width;
  1063.     dst += Coded_Picture_Width;
  1064.     dst2 += Coded_Picture_Width;
  1065.     pu += Chroma_Width;
  1066.     pv += Chroma_Width;
  1067.   }
  1068. }
  1069.  
  1070.  
  1071. static void Dither_Top_Field420(unsigned char *src[],unsigned char *dst)
  1072. {
  1073.   int i,j;
  1074.   int Y1,Cb1,Cr1,Y2,Cb2,Cr2;
  1075.   unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2;
  1076.  
  1077.   Y1_ptr = src[0];
  1078.   Cb1_ptr = src[1];
  1079.   Cr1_ptr = src[2];
  1080.  
  1081.   Y2_ptr = Y1_ptr + (Coded_Picture_Width<<1);
  1082.   Cb2_ptr = Cb1_ptr + (Chroma_Width<<1);
  1083.   Cr2_ptr = Cr1_ptr + (Chroma_Width<<1);
  1084.  
  1085.   dst2 = dst + Coded_Picture_Width;
  1086.  
  1087.   for (j=0; j<Coded_Picture_Height; j+=4)
  1088.   {
  1089.     /* line j + 0, j + 1 */
  1090.     for (i=0; i<Coded_Picture_Width; i+=4)
  1091.     {
  1092.       Y1 = *Y1_ptr++;
  1093.       Y2 = *Y2_ptr++;
  1094.       Cb1 = *Cb1_ptr++ >> 1;
  1095.       Cr1 = *Cr1_ptr++ >> 1;
  1096.       Cb2 = *Cb2_ptr++ >> 1;
  1097.       Cr2 = *Cr2_ptr++ >> 1;
  1098.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)]|Cb_Table[Cb1]|Cr_Table[Cr1]];
  1099.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+12]|Cb_Table[((3*Cb1+Cb2)>>2)+12]
  1100.                                              |Cr_Table[((3*Cr1+Cr2)>>2)+12]];
  1101.  
  1102.       Y1 = *Y1_ptr++;
  1103.       Y2 = *Y2_ptr++;
  1104.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+8]|Cb_Table[Cb1+8]|Cr_Table[Cr1+8]];
  1105.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+4]|Cb_Table[((3*Cb1+Cb2)>>2)+4]
  1106.                                             |Cr_Table[((3*Cr1+Cr2)>>2)+4]];
  1107.  
  1108.       Y1 = *Y1_ptr++;
  1109.       Y2 = *Y2_ptr++;
  1110.       Cb1 = *Cb1_ptr++ >> 1;
  1111.       Cr1 = *Cr1_ptr++ >> 1;
  1112.       Cb2 = *Cb2_ptr++ >> 1;
  1113.       Cr2 = *Cr2_ptr++ >> 1;
  1114.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+2]|Cb_Table[Cb1+2]|Cr_Table[Cr1+2]];
  1115.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+14]|Cb_Table[((3*Cb1+Cb2)>>2)+14]
  1116.                                              |Cr_Table[((3*Cr1+Cr2)>>2)+14]];
  1117.  
  1118.       Y1 = *Y1_ptr++;
  1119.       Y2 = *Y2_ptr++;
  1120.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+10]|Cb_Table[Cb1+10]|Cr_Table[Cr1+10]];
  1121.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+6]|Cb_Table[((3*Cb1+Cb2)>>2)+6]
  1122.                                             |Cr_Table[((3*Cr1+Cr2)>>2)+6]];
  1123.     }
  1124.  
  1125.     Y1_ptr += Coded_Picture_Width;
  1126.  
  1127.     if (j!=(Coded_Picture_Height-4))
  1128.       Y2_ptr += Coded_Picture_Width;
  1129.     else
  1130.       Y2_ptr -= Coded_Picture_Width;
  1131.  
  1132.     Cb1_ptr -= Chroma_Width;
  1133.     Cr1_ptr -= Chroma_Width;
  1134.     Cb2_ptr -= Chroma_Width;
  1135.     Cr2_ptr -= Chroma_Width;
  1136.  
  1137.     dst  += Coded_Picture_Width;
  1138.     dst2 += Coded_Picture_Width;
  1139.  
  1140.     /* line j + 2, j + 3 */
  1141.     for (i=0; i<Coded_Picture_Width; i+=4)
  1142.     {
  1143.       Y1 = *Y1_ptr++;
  1144.       Y2 = *Y2_ptr++;
  1145.       Cb1 = *Cb1_ptr++ >> 1;
  1146.       Cr1 = *Cr1_ptr++ >> 1;
  1147.       Cb2 = *Cb2_ptr++ >> 1;
  1148.       Cr2 = *Cr2_ptr++ >> 1;
  1149.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+3]|Cb_Table[((Cb1+Cb2)>>1)+3]
  1150.                                             |Cr_Table[((Cr1+Cr2)>>1)+3]];
  1151.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+15]|Cb_Table[((Cb1+3*Cb2)>>2)+15]
  1152.                                              |Cr_Table[((Cr1+3*Cr2)>>2)+15]];
  1153.  
  1154.       Y1 = *Y1_ptr++;
  1155.       Y2 = *Y2_ptr++;
  1156.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+11]|Cb_Table[((Cb1+Cb2)>>1)+11]
  1157.                                              |Cr_Table[((Cr1+Cr2)>>1)+11]];
  1158.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+7]|Cb_Table[((Cb1+3*Cb2)>>2)+7]
  1159.                                             |Cr_Table[((Cr1+3*Cr2)>>2)+7]];
  1160.  
  1161.       Y1 = *Y1_ptr++;
  1162.       Y2 = *Y2_ptr++;
  1163.       Cb1 = *Cb1_ptr++ >> 1;
  1164.       Cr1 = *Cr1_ptr++ >> 1;
  1165.       Cb2 = *Cb2_ptr++ >> 1;
  1166.       Cr2 = *Cr2_ptr++ >> 1;
  1167.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+1]|Cb_Table[((Cb1+Cb2)>>1)+1]
  1168.                                             |Cr_Table[((Cr1+Cr2)>>1)+1]];
  1169.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+13]|Cb_Table[((Cb1+3*Cb2)>>2)+13]
  1170.                                              |Cr_Table[((Cr1+3*Cr2)>>2)+13]];
  1171.  
  1172.       Y1 = *Y1_ptr++;
  1173.       Y2 = *Y2_ptr++;
  1174.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+9]|Cb_Table[((Cb1+Cb2)>>1)+9]
  1175.                                             |Cr_Table[((Cr1+Cr2)>>1)+9]];
  1176.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+5]|Cb_Table[((Cb1+3*Cb2)>>2)+5]
  1177.                                             |Cr_Table[((Cr1+3*Cr2)>>2)+5]];
  1178.     }
  1179.  
  1180.     Y1_ptr += Coded_Picture_Width;
  1181.     Y2_ptr += Coded_Picture_Width;
  1182.     Cb1_ptr += Chroma_Width;
  1183.     Cr1_ptr += Chroma_Width;
  1184.     if (j!=(Coded_Picture_Height-8))
  1185.     {
  1186.       Cb2_ptr += Chroma_Width;
  1187.       Cr2_ptr += Chroma_Width;
  1188.     }
  1189.     else
  1190.     {
  1191.       Cb2_ptr -= Chroma_Width;
  1192.       Cr2_ptr -= Chroma_Width;
  1193.     }
  1194.     dst += Coded_Picture_Width;
  1195.     dst2+= Coded_Picture_Width;
  1196.   }
  1197. }
  1198.  
  1199.  
  1200. static void Dither_Bottom_Field420(unsigned char *src[],unsigned char *dst)
  1201. {
  1202.   int i,j;
  1203.   int Y1,Cb1,Cr1,Y2,Cb2,Cr2;
  1204.   unsigned char *Y1_ptr,*Cb1_ptr,*Cr1_ptr,*Y2_ptr,*Cb2_ptr,*Cr2_ptr,*dst2;
  1205.  
  1206.   Y2_ptr = Y1_ptr = src[0] + Coded_Picture_Width;
  1207.   Cb2_ptr = Cb1_ptr = src[1] + Chroma_Width;
  1208.   Cr2_ptr = Cr1_ptr = src[2] + Chroma_Width;
  1209.  
  1210.   dst2 = dst;
  1211.  
  1212.   for (j=0; j<Coded_Picture_Height; j+=4)
  1213.   {
  1214.     /* line j + 0, j + 1 */
  1215.     for (i=0; i<Coded_Picture_Width; i+=4)
  1216.     {
  1217.       Y1 = *Y1_ptr++;
  1218.       Y2 = *Y2_ptr++;
  1219.       Cb1 = *Cb1_ptr++ >> 1;
  1220.       Cr1 = *Cr1_ptr++ >> 1;
  1221.       Cb2 = *Cb2_ptr++ >> 1;
  1222.       Cr2 = *Cr2_ptr++ >> 1;
  1223.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15]
  1224.                                              |Cr_Table[((3*Cr1+Cr2)>>2)+15]];
  1225.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)]|Cb_Table[((Cb1+Cb2)>>1)]
  1226.                                           |Cr_Table[((Cr1+Cr2)>>1)]];
  1227.  
  1228.       Y1 = *Y1_ptr++;
  1229.       Y2 = *Y2_ptr++;
  1230.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7]
  1231.                                             |Cr_Table[((3*Cr1+Cr2)>>2)+7]];
  1232.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+8]|Cb_Table[((Cb1+Cb2)>>1)+8]
  1233.                                             |Cr_Table[((Cr1+Cr2)>>1)+8]];
  1234.  
  1235.       Y1 = *Y1_ptr++;
  1236.       Y2 = *Y2_ptr++;
  1237.       Cb1 = *Cb1_ptr++ >> 1;
  1238.       Cr1 = *Cr1_ptr++ >> 1;
  1239.       Cb2 = *Cb2_ptr++ >> 1;
  1240.       Cr2 = *Cr2_ptr++ >> 1;
  1241.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13]
  1242.                                              |Cr_Table[((3*Cr1+Cr2)>>2)+13]];
  1243.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+2]|Cb_Table[((Cb1+Cb2)>>1)+2]
  1244.                                             |Cr_Table[((Cr1+Cr2)>>1)+2]];
  1245.  
  1246.       Y1 = *Y1_ptr++;
  1247.       Y2 = *Y2_ptr++;
  1248.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5]
  1249.                                             |Cr_Table[((3*Cr1+Cr2)>>2)+5]];
  1250.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+10]|Cb_Table[((Cb1+Cb2)>>1)+10]
  1251.                                              |Cr_Table[((Cr1+Cr2)>>1)+10]];
  1252.     }
  1253.  
  1254.     if (j!=0)
  1255.       Y1_ptr += Coded_Picture_Width;
  1256.     else
  1257.       Y1_ptr -= Coded_Picture_Width;
  1258.  
  1259.     Y2_ptr += Coded_Picture_Width;
  1260.  
  1261.     Cb1_ptr -= Chroma_Width;
  1262.     Cr1_ptr -= Chroma_Width;
  1263.     Cb2_ptr -= Chroma_Width;
  1264.     Cr2_ptr -= Chroma_Width;
  1265.  
  1266.     if (j!=0)
  1267.       dst  += Coded_Picture_Width;
  1268.  
  1269.     dst2 += Coded_Picture_Width;
  1270.  
  1271.     /* line j + 2, j + 3 */
  1272.     for (i=0; i<Coded_Picture_Width; i+=4)
  1273.     {
  1274.       Y1 = *Y1_ptr++;
  1275.       Y2 = *Y2_ptr++;
  1276.       Cb1 = *Cb1_ptr++ >> 1;
  1277.       Cr1 = *Cr1_ptr++ >> 1;
  1278.       Cb2 = *Cb2_ptr++ >> 1;
  1279.       Cr2 = *Cr2_ptr++ >> 1;
  1280.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+12]|Cb_Table[((Cb1+3*Cb2)>>2)+12]
  1281.                                              |Cr_Table[((Cr1+3*Cr2)>>2)+12]];
  1282.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+3]|Cb_Table[Cb2+3]
  1283.                                             |Cr_Table[Cr2+3]];
  1284.  
  1285.       Y1 = *Y1_ptr++;
  1286.       Y2 = *Y2_ptr++;
  1287.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+4]|Cb_Table[((Cb1+3*Cb2)>>2)+4]
  1288.                                             |Cr_Table[((Cr1+3*Cr2)>>2)+4]];
  1289.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+11]|Cb_Table[Cb2+11]
  1290.                                              |Cr_Table[Cr2+11]];
  1291.  
  1292.       Y1 = *Y1_ptr++;
  1293.       Y2 = *Y2_ptr++;
  1294.       Cb1 = *Cb1_ptr++ >> 1;
  1295.       Cr1 = *Cr1_ptr++ >> 1;
  1296.       Cb2 = *Cb2_ptr++ >> 1;
  1297.       Cr2 = *Cr2_ptr++ >> 1;
  1298.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+14]|Cb_Table[((Cb1+3*Cb2)>>2)+14]
  1299.                                              |Cr_Table[((Cr1+3*Cr2)>>2)+14]];
  1300.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+1]|Cb_Table[Cb2+1]
  1301.                                             |Cr_Table[Cr2+1]];
  1302.  
  1303.       Y1 = *Y1_ptr++;
  1304.       Y2 = *Y2_ptr++;
  1305.       *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+6]|Cb_Table[((Cb1+3*Cb2)>>2)+6]
  1306.                                             |Cr_Table[((Cr1+3*Cr2)>>2)+6]];
  1307.       *dst2++ = Pixel[Y_Table[((Y1+3*Y2)>>2)+9]|Cb_Table[Cb2+9]
  1308.                                             |Cr_Table[Cr2+9]];
  1309.     }
  1310.  
  1311.     Y1_ptr += Coded_Picture_Width;
  1312.     Y2_ptr += Coded_Picture_Width;
  1313.  
  1314.     if (j!=0)
  1315.     {
  1316.       Cb1_ptr += Chroma_Width;
  1317.       Cr1_ptr += Chroma_Width;
  1318.     }
  1319.     else
  1320.     {
  1321.       Cb1_ptr -= Chroma_Width;
  1322.       Cr1_ptr -= Chroma_Width;
  1323.     }
  1324.  
  1325.     Cb2_ptr += Chroma_Width;
  1326.     Cr2_ptr += Chroma_Width;
  1327.  
  1328.     dst += Coded_Picture_Width;
  1329.     dst2+= Coded_Picture_Width;
  1330.   }
  1331.  
  1332.   Y2_ptr -= (Coded_Picture_Width<<1);
  1333.   Cb2_ptr -= (Chroma_Width<<1);
  1334.   Cr2_ptr -= (Chroma_Width<<1);
  1335.  
  1336.   /* dither last line */
  1337.   for (i=0; i<Coded_Picture_Width; i+=4)
  1338.   {
  1339.     Y1 = *Y1_ptr++;
  1340.     Y2 = *Y2_ptr++;
  1341.     Cb1 = *Cb1_ptr++ >> 1;
  1342.     Cr1 = *Cr1_ptr++ >> 1;
  1343.     Cb2 = *Cb2_ptr++ >> 1;
  1344.     Cr2 = *Cr2_ptr++ >> 1;
  1345.     *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+15]|Cb_Table[((3*Cb1+Cb2)>>2)+15]
  1346.                                            |Cr_Table[((3*Cr1+Cr2)>>2)+15]];
  1347.  
  1348.     Y1 = *Y1_ptr++;
  1349.     Y2 = *Y2_ptr++;
  1350.     *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+7]|Cb_Table[((3*Cb1+Cb2)>>2)+7]
  1351.                                           |Cr_Table[((3*Cr1+Cr2)>>2)+7]];
  1352.  
  1353.     Y1 = *Y1_ptr++;
  1354.     Y2 = *Y2_ptr++;
  1355.     Cb1 = *Cb1_ptr++ >> 1;
  1356.     Cr1 = *Cr1_ptr++ >> 1;
  1357.     Cb2 = *Cb2_ptr++ >> 1;
  1358.     Cr2 = *Cr2_ptr++ >> 1;
  1359.     *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+13]|Cb_Table[((3*Cb1+Cb2)>>2)+13]
  1360.                                            |Cr_Table[((3*Cr1+Cr2)>>2)+13]];
  1361.  
  1362.     Y1 = *Y1_ptr++;
  1363.     Y2 = *Y2_ptr++;
  1364.     *dst++  = Pixel[Y_Table[((3*Y1+Y2)>>2)+5]|Cb_Table[((3*Cb1+Cb2)>>2)+5]
  1365.                                           |Cr_Table[((3*Cr1+Cr2)>>2)+5]];
  1366.     }
  1367.  
  1368. }
  1369.  
  1370.  
  1371. #define twomerges1(a, b, c, d, shift, mask) \
  1372.   { \
  1373.   temp1 = b; \
  1374.   temp2 = d; \
  1375.   temp1 >>= shift; \
  1376.   temp2 >>= shift; \
  1377.   temp1 ^= a; \
  1378.   temp2 ^= c; \
  1379.   temp1 &= mask; \
  1380.   temp2 &= mask; \
  1381.   a ^= temp1; \
  1382.   c ^= temp2; \
  1383.   temp1 <<= shift; \
  1384.   temp2 <<= shift; \
  1385.   b ^= temp1; \
  1386.   d ^= temp2; \
  1387.   }
  1388.  
  1389. #define twomerges2(a, b, c, d, shift, mask) \
  1390.   { \
  1391.   temp1 = (a ^ (b >> shift)) & mask; \
  1392.   temp2 = (c ^ (d >> shift)) & mask; \
  1393.   a ^= temp1; \
  1394.   c ^= temp2; \
  1395.   b ^= temp1 << shift; \
  1396.   d ^= temp2 << shift; \
  1397.   }
  1398.  
  1399.  
  1400. static void c2p1x1_8_c5_ppc(void *chunky, void *bitplanes,
  1401.                             int chunkyx, int chunkyy,
  1402.                             int xoffset, int yoffset,
  1403.                             int bitplanesize)
  1404. {
  1405.   ULONG *c;
  1406.   ULONG temp1, temp2;
  1407.   ULONG *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
  1408.   ULONG d0, d1, d2, d3, d4, d5, d6, d7;
  1409.   ULONG t0, t1, t2, t3, t4, t5, t6, t7;
  1410.   int i;
  1411.  
  1412.   c = (ULONG *) chunky;
  1413.   p0 = (ULONG *) (&(((char *) bitplanes)[yoffset * chunkyx >> 3]));
  1414.   p1 = (ULONG *) (&(((char *) p0)[bitplanesize]));
  1415.   p2 = (ULONG *) (&(((char *) p1)[bitplanesize]));
  1416.   p3 = (ULONG *) (&(((char *) p2)[bitplanesize]));
  1417.   p4 = (ULONG *) (&(((char *) p3)[bitplanesize]));
  1418.   p5 = (ULONG *) (&(((char *) p4)[bitplanesize]));
  1419.   p6 = (ULONG *) (&(((char *) p5)[bitplanesize]));
  1420.   p7 = (ULONG *) (&(((char *) p6)[bitplanesize]));
  1421.  
  1422.   i = chunkyx * chunkyy / (sizeof (ULONG) * 8);
  1423.  
  1424.   d0 = *c++;
  1425.   d1 = *c++;
  1426.   d2 = *c++;
  1427.   d3 = *c++;
  1428.   d4 = *c++;
  1429.   d5 = *c++;
  1430.   d6 = *c++;
  1431.   d7 = *c++;
  1432.  
  1433.   twomerges1(d0, d4, d1, d5, 16, 0x0000ffff);
  1434.   twomerges1(d2, d6, d3, d7, 16, 0x0000ffff);
  1435.  
  1436.   twomerges1(d0, d2, d1, d3, 8, 0x00ff00ff);
  1437.   twomerges1(d4, d6, d5, d7, 8, 0x00ff00ff);
  1438.  
  1439.   twomerges1(d0, d1, d2, d3, 4, 0x0f0f0f0f);
  1440.   twomerges1(d4, d5, d6, d7, 4, 0x0f0f0f0f);
  1441.  
  1442.   twomerges1(d0, d4, d1, d5, 2, 0x33333333);
  1443.   twomerges1(d2, d6, d3, d7, 2, 0x33333333);
  1444.  
  1445.   twomerges1(d0, d2, d1, d3, 1, 0x55555555);
  1446.   twomerges1(d4, d6, d5, d7, 1, 0x55555555);
  1447.  
  1448.   t0 = d7;
  1449.   t1 = d5;
  1450.   t2 = d3;
  1451.   t3 = d1;
  1452.   t4 = d6;
  1453.   t5 = d4;
  1454.   t6 = d2;
  1455.   t7 = d0;
  1456.  
  1457.   while (--i)
  1458.   {
  1459.     d0 = *c++;
  1460.     d1 = *c++;
  1461.     d2 = *c++;
  1462.     d3 = *c++;
  1463.     d4 = *c++;
  1464.     d5 = *c++;
  1465.     d6 = *c++;
  1466.     d7 = *c++;
  1467.  
  1468.     *p0++ = t0;
  1469.  
  1470.     twomerges1(d0, d4, d1, d5, 16, 0x0000ffff);
  1471.     twomerges1(d2, d6, d3, d7, 16, 0x0000ffff);
  1472.  
  1473.     *p1++ = t1;
  1474.  
  1475.     twomerges1(d0, d2, d1, d3, 8, 0x00ff00ff);
  1476.     twomerges1(d4, d6, d5, d7, 8, 0x00ff00ff);
  1477.  
  1478.     *p2++ = t2;
  1479.  
  1480.     twomerges1(d0, d1, d2, d3, 4, 0x0f0f0f0f);
  1481.     twomerges1(d4, d5, d6, d7, 4, 0x0f0f0f0f);
  1482.  
  1483.     *p3++ = t3;
  1484.  
  1485.     twomerges1(d0, d4, d1, d5, 2, 0x33333333);
  1486.     twomerges1(d2, d6, d3, d7, 2, 0x33333333);
  1487.  
  1488.     *p4++ = t4;
  1489.  
  1490.     twomerges1(d0, d2, d1, d3, 1, 0x55555555);
  1491.     twomerges1(d4, d6, d5, d7, 1, 0x55555555);
  1492.  
  1493.     *p5++ = t5;
  1494.     *p6++ = t6;
  1495.     *p7++ = t7;
  1496.  
  1497.     t0 = d7;
  1498.     t1 = d5;
  1499.     t2 = d3;
  1500.     t3 = d1;
  1501.     t4 = d6;
  1502.     t5 = d4;
  1503.     t6 = d2;
  1504.     t7 = d0;
  1505.  
  1506.   }
  1507.  
  1508.   *p0++ = t0;
  1509.   *p1++ = t1;
  1510.   *p2++ = t2;
  1511.   *p3++ = t3;
  1512.   *p4++ = t4;
  1513.   *p5++ = t5;
  1514.   *p6++ = t6;
  1515.   *p7++ = t7;
  1516. }
  1517.  
  1518. #endif /* DISPLAY */
  1519.